package cos480.amiwsd;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.LinkedList;

public class PSSTulator {

	private Connection con;
	private Statement sql;
	
	//assorted managers
	private DBMgmt dbMgmt;
	private GenMgmt genMgmt;
	private SearchMgmt sMgmt;
	private GetMgmt getMgmt;
	private AddMgmt addMgmt;
	private String user;
	
	public PSSTulator () {
		
		this.con = null;
		this.sql = null;
		this.dbMgmt = new DBMgmt();
		this.genMgmt = new GenMgmt();
		this.sMgmt = new SearchMgmt();
		this.getMgmt = new GetMgmt();
		this.addMgmt = new AddMgmt();
		this.user = null;
		
	}
	
	/**
	 * Define a persistent query; Store the given query string
	 * in the DB along with the given identifier as its name. 
	 * 
	 * @param name identifier of the stored query
	 * @param query the query string to store
	 */
	public void define(String name, String query){
		try{
			if(query != null)
				sql.executeUpdate("insert into psstdefinition values ('" + name + "', '" + query + "')");
		} catch(SQLException e){
			e.printStackTrace();
		}
	}
	
	public String addSimResult(String s) {
		
		try {
			return addMgmt.addSimResult(con, s);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
		
	}
	
	public String searchSimResults(HashMap<String,String> s) {
		
		return sMgmt.searchSimResults(sql, s);
		
	}
	
	public String searchSimParams(HashMap<String,String> s) {
		
		return sMgmt.searchSimParams(sql, s);
		
	}
	
	public String searchScanResults(HashMap<String,String> s) {
		
		return sMgmt.searchScanResults(sql, s);
		
	}
	
	public String genLand() {
		
		return genMgmt.genLand(sql);
		
	}
	
	public String genLand(LinkedList<String> d) {
		
		return genMgmt.genLand(sql, d);
		
	}
	
	public String getIPs(HashMap<String, String> pl) {
		
		try {
			return getMgmt.getIPs(sql, pl);	
		} catch (Exception e) {
			System.err.println("Failed to recieve the where clause returned by getMgmt.getIPs");
			e.printStackTrace();
		}
		
		return null;
	}
	
	/**
	 * Adds a list of scanned IP addresses and the scan results
	 * to the database.
	 * 
	 * Parameters:
	 * -- filename: path to the scan output file
	 * -- success: s=success; f=failed; e=empty
	 * -- date: date of the scan that produced these results
	 * 
	 * @param pl map of params:values for adding IPs
	 * @return null; saving "add"s not currently permitted
	 */
	public String addIPs(HashMap<String, String> pl) {
		
		try {
			return addMgmt.addIPs(sql, pl);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
		
	}
	
	public String genParams(HashMap<String,String> pl){
		try {
			return genMgmt.genSimParams(con, pl);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * tableChecks:
	 * 
	 * Top-level call to check and create AMIWSD tables. 
	 * 
	 */
	
	public void tableChecks() {
		
		if(!dbMgmt.tableCheck(sql, "host")) {
			dbMgmt.createHostTable(sql);
		}
		if(!dbMgmt.tableCheck(sql, "simulation") && !dbMgmt.tableCheck(sql, "simresult")) {
			dbMgmt.createSimTable(sql);
		}
		if(!dbMgmt.tableCheck(sql, "scan")) {
			dbMgmt.createScanTable(sql);
		}
		if(!dbMgmt.tableCheck(sql, "resultofscan")){
			dbMgmt.createResultOfScanTable(sql);
		}
		if(!dbMgmt.tableCheck(sql, "psstdefinition")){
			dbMgmt.createPSSTDefinitionTable(sql);
		}
		if(!dbMgmt.tableCheck(sql, "landscape")) {
			dbMgmt.createLandscape(sql);
		}
		if(!dbMgmt.tableCheck(sql, "instance")) {
			dbMgmt.createInstance(sql);
		}
		//Add other statements for each table here once they're complete.
		
	}
	
	public void connect(String[] userpass) {
		
		try {
			this.con = this.dbMgmt.connect(userpass);
			this.sql = con.createStatement();
			this.user = userpass[0];
			
		} catch (SQLException e) {
			System.err.println("Failed to connect to the database '" + userpass[0] + "': " + e.getMessage());
			e.printStackTrace();
			return;
		}
		
		//only both if connection is successful.
		this.tableChecks();
	}
	
	public void disconnect() {
	
		try {
			this.con.close();
		} catch (SQLException e) {
			System.err.println("Failed to close the current connection: " + e.getMessage());
			e.printStackTrace();
		}
		System.out.println("Goodbye!");
		System.exit(0);
	}
	
	
}
